<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Develop\Ctl;

use Srv\Apps\Proto\DTO\Develop\BadWordAddDTO;
use Srv\Apps\Proto\DTO\Develop\BadWordEditDTO;
use Srv\Apps\Proto\DTO\Develop\BadWordListDTO;
use Srv\Apps\Proto\Enum\Common\BadWordTypeEnum;
use Srv\Apps\Proto\Enum\YesOrNoEnum;
use Srv\Apps\Proto\VO\Develop\BadWordListVO;
use Srv\Apps\Proto\VO\Develop\BadWordVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class BadWordCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write

    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $stbwId
     * @return array
     * getBadWordSrc
     */
    public function getBadWordSrc(int $stbwId):array
    {
        if($stbwId < 1) return [];
        $isFail     = false;
        $info       = $this->DbAuto->getDataOne('SELECT stbw_id, stbw_type, stbw_keyword, stbw_enable, stbw_create_time, stbw_update_time FROM '.$this->DbAuto->getTableNameAll('set_bad_word').' WHERE stbw_id='.$stbwId.' AND stbw_delete=0', $isFail);
        if($isFail || !isset($info['stbw_id'])) return [];
        return $info;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return BadWordListVO|null
     * getBadWordList
     */
    public function getBadWordList(Page $Page, array $whereData): ?BadWordListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE stbw_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case BadWordListDTO::_stbwId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'stbw_id='. intval($val);
                    break;
                case BadWordListDTO::_keyword:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'stbw_keyword LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case BadWordListDTO::_type:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'stbw_type='. intval($val);
                    break;
                case BadWordListDTO::_enable:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'stbw_enable='. intval($val);
                    break;
            }
        }
        $isFail             = false;
        $sql                = 'SELECT SQL_CALC_FOUND_ROWS stbw_id, stbw_type, stbw_keyword, stbw_enable, stbw_create_time, stbw_update_time FROM '.$this->DbAuto->getTableNameAll('set_bad_word').$whereString.' ORDER BY stbw_id DESC '.$limitString;
        $list               = $this->DbAuto->getData($sql, $isFail);
        $totalNum           = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $BadWordVOList      = [];
        if(CommArray::isForeach($list))foreach($list as $item){
            $stbwIdItem         = intval($item['stbw_id']);
            if($stbwIdItem < 1) continue;
            $BadWordVO          = $this->getBadWordVO($item);
            if(!($BadWordVO instanceof BadWordVO)) continue;
            $BadWordVOList[]    = $BadWordVO;
        }
        $BadWordListVO          = new BadWordListVO();
        $BadWordListVO->setList($BadWordVOList);
        $BadWordListVO->setPage($Page->getPageVO($totalNum));
        return $BadWordListVO;
    }

    /**
     * @param int $stbwId
     * @return BadWordVO|null
     * getBadWordInfo
     */
    public function getBadWordInfo(int $stbwId):?BadWordVO
    {
        $badWordSrc     = $this->getBadWordSrc($stbwId);
        if(!isset($badWordSrc['stbw_id'])) return null;
        return $this->getBadWordVO($badWordSrc);
    }

    /**
     * @param array $info
     * @return BadWordVO|null
     * getBadWordVO
     */
    public function getBadWordVO(array $info): ?BadWordVO
    {
        $stbwId         = intval($info['stbw_id']??0);
        if($stbwId < 1) return null;
        $BadWordVO      = new BadWordVO();
        $BadWordVO->setStbwId($stbwId);
        $BadWordVO->setType(BadWordTypeEnum::parseValue($info['stbw_type']));
        $BadWordVO->setKeyword(trim($info['stbw_keyword']));
        $BadWordVO->setEnable(YesOrNoEnum::parseValue($info['stbw_enable']));
        $BadWordVO->setCreateTime(intval($info['stbw_create_time']));
        $BadWordVO->setUpdateTime(intval($info['stbw_update_time']));
        return $BadWordVO;
    }

    /**
     * @param array $setData
     * @return int
     * badWordAdd
     */
    public function badWordAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $currTime   = CommTime::getTimeStamp();
        $setString  = '';
        foreach ($setData as $key => $val){
            switch ($key){
                case BadWordAddDTO::_keyword:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_keyword=\''.$this->DbAuto->getRealEscapeString($val) .'\'';
                    break;
                case BadWordAddDTO::_type:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_type='.intval($val);
                    break;
                case BadWordAddDTO::_enable:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_enable='.intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return 0;
        $isFail     = false;
        $sql        = 'INSERT INTO '.$this->DbAuto->getTableNameAll('set_bad_word').' SET '.$setString.', stbw_create_time='.$currTime.', stbw_update_time='.$currTime;
        $stbwId     = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $stbwId < 1) return 0;
        return $stbwId;
    }

    /**
     * @param int $stbwId
     * @param array $setData
     * @return bool
     * badWordEdit
     */
    public function badWordEdit(int $stbwId, array $setData):bool
    {
        if($stbwId < 1 || count($setData) < 1) return false;
        $currTime       = CommTime::getTimeStamp();
        $setString      = '';
        foreach ($setData as $key => $val){
            switch ($key){
                case BadWordEditDTO::_type:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_type='.intval($val);
                    break;
                case BadWordEditDTO::_keyword:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_keyword=\''.$this->DbAuto->getRealEscapeString($val) .'\'';
                    break;
                case BadWordEditDTO::_enable:
                    $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'stbw_enable='.intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return false;
        $isFail     = false;
        $sql        = 'UPDATE '.$this->DbAuto->getTableNameAll('set_bad_word').' SET '.$setString.', stbw_update_time='.$currTime.' WHERE stbw_id='.$stbwId.' AND stbw_delete=0';
        $this->DbAuto->getDataNum($sql, $isFail);
        if($isFail) return false;
        return true;
    }
}